package anc.tankshooter.map;

import java.util.ArrayList;

import org.andengine.entity.scene.Scene;
import org.andengine.extension.tmx.TMXLayer;
import org.andengine.extension.tmx.TMXLoader;
import org.andengine.extension.tmx.TMXTile;
import org.andengine.extension.tmx.TMXTileSet;
import org.andengine.extension.tmx.TMXTiledMap;
import org.andengine.opengl.texture.TextureManager;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import anc.tankshooter.models.ITank;
import android.content.res.AssetManager;

public class GameMap {

	public static int iv[]={-1,0,1,0};
    public static int jv[]={0,1,0,-1};
    
	public static final int MAP_COLUMNS = 25;
	public static final int MAP_ROWS = 15;
	public static final int TITLE_WIDTH = 32;
	public static final int TITLE_HEIGHT = 32;
	
	private int[][] mMarkedMatrix;
	
	private TMXTiledMap mMap;
	private AssetManager mAsset;
	private TextureManager mTextureManager;
	private VertexBufferObjectManager mVbom;
	private TMXLoader mMapLoader;
	
	private ArrayList<TMXLayer> mMapLayers;
	public GameMap(AssetManager asset,TextureManager textureManager,VertexBufferObjectManager vbom){
		
		mMarkedMatrix = new int[MAP_ROWS][MAP_COLUMNS];
		mAsset=asset;
		mTextureManager=textureManager;
		mVbom=vbom;
		mMapLoader = new TMXLoader(mAsset, mTextureManager, TextureOptions.BILINEAR_PREMULTIPLYALPHA, mVbom, null);
	}

	public boolean loadMap(int index) {
		boolean isSuccess= false;
		try{
			mMap = mMapLoader.loadFromAsset(index+".tmx");
			mMapLayers = mMap.getTMXLayers();
			isSuccess=true;
		}catch(Exception ex){
			ex.getMessage();
		}
		return isSuccess;
	}
	
	/**
	 * Lấy ma trận trạng thái của bản đồ.
	 * Được sử dụng bỏi thuật toán A*
	 * @return
	 */
	public void updateMarkedMatrix(ArrayList<ITank> itanks){
		
		TMXTile[][] titles2 = getBreakableObstacle().getTMXTiles();
		TMXTile[][] titles3 = getUnbreakableObstacle().getTMXTiles();
		for (int i = 0; i < GameMap.MAP_ROWS; i++) {
			for (int j = 0; j < GameMap.MAP_COLUMNS; j++) {
				int id2 = titles2[i][j].getGlobalTileID();
				int id3 = titles3[i][j].getGlobalTileID();
				if(isObstacle(id2))
					mMarkedMatrix[i][j] = 1;
				else if(isObstacle(id3))
					mMarkedMatrix[i][j] = 1;
				else mMarkedMatrix[i][j] = 0;
			}
		}
		for (int i = 0; i < itanks.size(); i++) {
			ITank tank = itanks.get(i);
			int ni = (int)(tank.getY()/GameMap.TITLE_HEIGHT);
			int nj = (int)(tank.getX()/GameMap.TITLE_WIDTH);
			if( ni>=0 && nj>=0 && ni < GameMap.MAP_ROWS&&nj<GameMap.MAP_COLUMNS){
				mMarkedMatrix[ni][nj] = 1;
				if(tank.isMoving){
					mMarkedMatrix[tank.getNPY()][tank.getNPX()] = 1;
				}
			}
		}
		
	}
	
	public int[][] getMatrix(){
		return mMarkedMatrix;
	}
	
	
	public void showMap(Scene scene){
		if(mMap!=null){
			for (TMXLayer layer : mMap.getTMXLayers()) {
				scene.attachChild(layer);
			}
		}
		
	}
	

	/**
	 * Kiểm tra xem title có id là titleId có phải là vật cản hay không.
	 * @param titleId
	 * @return true nếu đúng và ngược lại
	 */
	public boolean isObstacle(int titleId) {
		
		boolean isTitle= true;
		for(TMXTileSet set : mMap.getTMXTileSets())
		{
			if(titleId == set.getFirstGlobalTileID()){
				isTitle=false;
				break;
			}
		}
		return isTitle;
	}
	
	/**
	 * Pha huy 1 doi tuong tren map
	 * @param tx : Chỉ số cột
	 * @param ty : Chỉ số dòng
	 */
	public void destroyTile(int tx, int ty)
	{
		TMXTile destroyedTile = getBreakableObstacle().getTMXTile(tx, ty);
		int firstTitleId = this.getFirstTitleIdOf(destroyedTile.getGlobalTileID());
		if(firstTitleId>0){
			destroyedTile.setGlobalTileID(mMap, firstTitleId);
			
			int tileHeigh = mMap.getTileHeight();
			int tileWidth = mMap.getTileWidth();
			getBreakableObstacle().setIndex(destroyedTile.getTileRow() * mMap.getTileColumns() + destroyedTile.getTileColumn());
			getBreakableObstacle().drawWithoutChecks(destroyedTile.getTextureRegion(), 
														 destroyedTile.getTileX(), 
														 destroyedTile.getTileY(), 
														 tileWidth, tileHeigh, org.andengine.util.color.Color.WHITE_ABGR_PACKED_FLOAT);
			getBreakableObstacle().submit();
		}
	}
	
	

	/**
	 * Lấy layer chứa tất cả vật cản có thể bắn vỡ đc
	 * @return
	 */
	public TMXLayer getBreakableObstacle(){
		return mMapLayers.get(2);
	}
	/**
	 * Lấy layer chứa tất cả vật cản không bắn vỡ đc
	 * @return
	 */
	public TMXLayer getUnbreakableObstacle(){
		return mMapLayers.get(3);
	}
	
	/**
	 * Kiểm tra và lấy title đầu tiên(ô title trong suốt ) nằm cùng titleset với
	 * title có id = titleId
	 * @param titleId
	 * @return 0 Nếu không tìm thấy.
	 */
	public int getFirstTitleIdOf(int titleId){
		int firstTitleId = 0;
		for(int i=mMap.getTMXTileSets().size()-1;i>=0;i--)
		{
			if(titleId >= mMap.getTMXTileSets().get(i).getFirstGlobalTileID()){
				firstTitleId = mMap.getTMXTileSets().get(i).getFirstGlobalTileID();
				break;
			}
		}
		return firstTitleId;
	}
}
